/* syscalls.h 
 * 	Nachos system call interface.  These are Nachos kernel operations
 * 	that can be invoked from user programs, by trapping to the kernel
 *	via the "syscall" instruction.
 *
 *	This file is included by user programs and by the Nachos kernel. 
 *
 * Copyright (c) 1992-1993 The Regents of the University of California.
 * All rights reserved.  See copyright.h for copyright notice and limitation 
 * of liability and disclaimer of warranty provisions.
 */

#ifndef SYSCALLS_H
#define SYSCALLS_H

#include "copyright.h"

/* system call codes -- used by the stubs to tell the kernel which system call
 * is being asked for
 */
#define SC_Halt		0
#define SC_Exit		1
#define SC_Exec		2
#define SC_Join		3
#define SC_Create	4
#define SC_Open		5
#define SC_Read		6
#define SC_Write	7
#define SC_Close	8
#define SC_Fork		9
#define SC_Yield	10

/*---------------------------------------------
// Added as Project2
// Support Lock and Condition Synchronization
// by OceanMaster
//---------------------------------------------*/
#define SC_CreateLock	11
#define SC_AcquireLock	12
#define SC_ReleaseLock	13
#define SC_DestroyLock	14

#define SC_CreateCondition		15
#define SC_WaitCondition		16
#define	SC_SignalCondition		17
#define SC_BroadcastCondition	18
#define SC_DestroyCondition		19

#define SC_WriteFormat			20
#define SC_Random				21

/*Added by shangsong Ji
 * System calls for distributed system
  */

#define SC_RemoteCreateLock		22
#define SC_RemoteAcquireLock		23
#define SC_RemoteReleaseLock            24
#define SC_RemoteDestroyLock		25
#define SC_RemoteCreateCondition	26
#define SC_RemoteWaitCondition		27
#define SC_RemoteSignalCondition	28
#define SC_RemoteBroadcastCondition	29
#define SC_RemoteDestroyCondition	30


/*
	Added by shangsong
	System calls for the operations of monitor variables
*/
#define SC_CreateMV				31
#define SC_GetMV				32
#define SC_SetMV				33
#define SC_DestroyMV			34

/*
   Added by shangsong
   System call for waiting the keyboard input
 */
#define SC_WaitInput			35
#define SC_ReadInput			36

/*---------------------------------------------
// Add end
//---------------------------------------------*/

#define MAXFILENAME 256

#ifndef IN_ASM

/* The system call interface.  These are the operations the Nachos
 * kernel needs to support, to be able to run user programs.
 *
 * Each of these is invoked by a user program by simply calling the 
 * procedure; an assembly language stub stuffs the system call code
 * into a register, and traps to the kernel.  The kernel procedures
 * are then invoked in the Nachos kernel, after appropriate error checking, 
 * from the system call entry point in exception.cc.
 */

/* Stop Nachos, and print out performance stats */
void Halt();		
 

/* Address space control operations: Exit, Exec, and Join */

/* This user program is done (status = 0 means exited normally). */
void Exit(int status);	

/* A unique identifier for an executing user program (address space) */
typedef int SpaceId;	
 
/* Run the executable, stored in the Nachos file "name", and return the 
 * address space identifier
 */
SpaceId Exec(char *name, int len);
 
/* Only return once the the user program "id" has finished.  
 * Return the exit status.
 */
int Join(SpaceId id); 	
 

/* File system operations: Create, Open, Read, Write, Close
 * These functions are patterned after UNIX -- files represent
 * both files *and* hardware I/O devices.
 *
 * If this assignment is done before doing the file system assignment,
 * note that the Nachos file system has a stub implementation, which
 * will work for the purposes of testing out these routines.
 */
 
/* A unique identifier for an open Nachos file. */
typedef int OpenFileId;	

/* when an address space starts up, it has two open files, representing 
 * keyboard input and display output (in UNIX terms, stdin and stdout).
 * Read and Write can be used directly on these, without first opening
 * the console device.
 */

#define ConsoleInput	0  
#define ConsoleOutput	1  
 
/* Create a Nachos file, with "name" */
void Create(char *name, int size);

/* Open the Nachos file "name", and return an "OpenFileId" that can 
 * be used to read and write to the file.
 */
OpenFileId Open(char *name, int size);

/* Write "size" bytes from "buffer" to the open file. */
void Write(char *buffer, int size, OpenFileId id);

/* Read "size" bytes from the open file into "buffer".  
 * Return the number of bytes actually read -- if the open file isn't
 * long enough, or if it is an I/O device, and there aren't enough 
 * characters to read, return whatever is available (for I/O devices, 
 * you should always wait until you can return at least one character).
 */
int Read(char *buffer, int size, OpenFileId id);

/* Close the file, we're done reading and writing to it. */
void Close(OpenFileId id);



/* User-level thread operations: Fork and Yield.  To allow multiple
 * threads to run within a user program. 
 */


/* Yield the CPU to another runnable thread, whether in this address space 
 * or not. 
 */
void Yield();		

/* Fork a thread to run a procedure ("func") in the *same* address space 
 * as the current thread.
 */
void Fork(void (*func)());


/*---------------------------------------------
// Added as Project2
// by OceanMaster
//---------------------------------------------*/

/*Create a Lock, passing name and name length, returns Lock indea*/
int CreateLock(char * name, int name_length);

/*Acquire a Lock, passing lock index*/
void AcquireLock(int lock_index);

/*Release a Lock, passing lock index*/
void ReleaseLock(int lock_index);

/*Destory a Lock, passing lock index*/
void DestroyLock(int lock_index);

/*Create a Condition Varible, passing name and name length, returns CV index*/
int CreateCV(char * name, int name_length);

/*Wait a Condition Varible, passing CV index and Lock index*/
void WaitCV(int CV_index, int lock_index);

/*Signal a Condition Varible, passing CV index and Lock index*/
void SignalCV(int CV_index, int lock_index);

/*Broadcast a Condition Varible, passing CV index and Lock index*/
void BroadcastCV(int CV_index, int lock_index);

/*Destroy a Condition Varible, passing CV index*/
void DestroyCV(int CV_index);

/*Write Function with Format support*/
/*Assumption, argnum < =6*/
void WriteFormat(char * format, int format_length, int * argument, int argnum);

/*Random function*/
/*Return a value randomly generated above 0 and less than argument*/
int Random(int limit);

/*Create a lock via RPC*/
int RemoteCreateLock(char* name,int name_length);

/*Acquire a lock via RPC*/
void RemoteAcquireLock(int lock_index);

/*Release a Lock, passing lock index via RPC*/
void RemoteReleaseLock(int lock_index);

/*Destory a Lock, passing lock index via RPC*/
void RemoteDestroyLock(int lock_index);

/*Create a Condition Varible via RPC, passing name and name length, returns CV index. */
int RemoteCreateCV(char * name, int name_length);


void RemoteWaitCV(int CV_index, int lock_index);

/*Signal a Condition Varible via RPC, passing CV index and Lock index*/
void RemoteSignalCV(int CV_index, int lock_index);

/*Broadcast a Condition Varible via RPC, passing CV index and Lock index*/
void RemoteBroadcastCV(int CV_index, int lock_index);

/*Destroy a Condition Varible via RPC, passing CV index*/
void RemoteDestroyCV(int CV_index);


/*---------------------------------------------
// Add end
//---------------------------------------------*/

/*Project 4 */
int CreateMV(char * name, int length, int arraylength, int initValue);
int GetMV(int MVId, int arrayIndex);
int SetMV(int MVId, int arrayIndex, int value);
int DestroyMV(int MVId);
void WaitInput();
int ReadInput(char * message, int length);

#endif /* IN_ASM */

#endif /* SYSCALL_H */
